package com.zhouyu;

import com.extend.AppConfig3;
import com.zhouyu.advice.ZhouyuAfterReturningAdvice;
import com.zhouyu.advice.ZhouyuBeforeAdvice;
import com.zhouyu.mapper.UserMapper;
import com.zhouyu.mybatis.spring.ZhouyuImportBeanDefinitionRegistrar;
import com.zhouyu.mybatis.spring.ZhouyuMapperScan;
import com.zhouyu.service.*;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.NameMatchMethodPointcut;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.CustomEditorConfigurer;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.*;
import org.springframework.context.support.ConversionServiceFactoryBean;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.beans.PropertyEditor;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

//@ComponentScan(value = "com.zhouyu",
//		excludeFilters = {
//			@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = UserService.class)
//		})

//@ComponentScan(value = "com.zhouyu",
//		includeFilters = {
//				@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = UserService.class)
//		})
//@ImportResource(value = "classpath:spring.xml")
//默认行为：如果不指定包路径，Spring会扫描当前配置类所在的包（即AppConfig的包路径）及其所有子包。
@ComponentScan(value = "com.zhouyu")
//@EnableScheduling
//@PropertySource(value = "classpath:spring.properties")
//@EnableAspectJAutoProxy
@EnableTransactionManagement
/**
 *@EnableAsync在发生循环依赖的时候，会报错
 */
@EnableAsync
@Configuration
//@Import(value = {ZhouyuImportSelector.class, ZhouyuImportBeanDefinitionRegistrar.class})
//@Import(value = {ZhouyuDeferredImportSelector.class})
//@ZhouyuMapperScan(value = "com.zhouyu.mapper")
//@MapperScan(value = "com.zhouyu.mapper")
//@Import(value = {DefaultAdvisorAutoProxyCreator.class})
//@Import(value = {ZhouyuImportSelector.class})
@Import(value = {AppConfig3.class})
public class AppConfig /*implements AppInterface*/ {


	//@Bean
	//public ProxyFactoryBean userService() {
	//	UserService userService = new UserService();
	//	ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
	//	proxyFactoryBean.addAdvice(new ZhouyuBeforeAdvice());
	//	proxyFactoryBean.setTarget(userService);
	//	return proxyFactoryBean;
	//}

	//@Bean
	//public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
	//	BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
	//	beanNameAutoProxyCreator.setBeanNames("userSe*");
	//	beanNameAutoProxyCreator.setInterceptorNames("zhouyuAroundAdvice");
	//	//beanNameAutoProxyCreator.setProxyTargetClass(true);
	//	return beanNameAutoProxyCreator;
	//}


	//@Bean
	//public DefaultPointcutAdvisor defaultPointcutAdvisor() {
	//	NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
	//	pointcut.addMethodName("test");
	//	DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
	//	defaultPointcutAdvisor.setPointcut(pointcut);
	//	defaultPointcutAdvisor.setAdvice(new ZhouyuAfterReturningAdvice());
	//	return defaultPointcutAdvisor;
	//}

	//@Bean
	//public static DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
	//	DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
	//	return defaultAdvisorAutoProxyCreator;
	//}


	//@Bean
	//public static MapperScannerConfigurer mapperScannerConfigurer() {
	//	MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
	//	mapperScannerConfigurer.setBasePackage("com.zhouyu.mapper");
	//	return mapperScannerConfigurer;
	//}


	//@Bean
	//public SqlSessionFactory sqlSessionFactory() throws IOException {
	//	InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
	//	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	//	return sqlSessionFactory;
	//}
	//
	//
	//@Bean
	//public SqlSession sqlSession() throws IOException {
	//
	//	SqlSession sqlSession = sqlSessionFactory().openSession();
	//	return sqlSession;
	//}

	///**
	// * 生成的BeanDefinition的className为null，不是配置类，里面的@Bean注解不会解析成BeanDefinition
	// *
	// * @return
	// */
	//@Bean
	//public AppConfig1 appConfig1() {
	//	return new AppConfig1();
	//}

	///**
	// * @Bean会覆盖掉扫描生成的BeanDefinition
	// *
	// * @return
	// */
	//@Bean
	//@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
	//public UserService userService() {
	//	return new UserService();
	//}


	//@Bean(autowire = Autowire.BY_TYPE)
	//public UserService userService() {
	//	return new UserService();
	//}

	//@Bean(autowire = Autowire.BY_TYPE)
	//@Bean(autowire = Autowire.BY_NAME)
	//public UserService userService() {
	//	return new UserService();
	//}

	//@Bean
	//public String number() {
	//	return "123456678990";
	//}

	//@Bean
	//public OrderService zhouyu() {
	//
	//	return new OrderService();
	//}

	///**
	// * factory-bean=appConfig
	// *
	// * factory-method=userService
	// *
	// *
	// * @return
	// */
	//@Bean
	//public UserService userService() {
	//	return new UserService();
	//}


	///**
	// * beanClass=AppConfig.class
	// *
	// * factory-method=userService
	// *
	// *
	// * @return
	// */
	//@Bean
	//public static UserService userService() {  //BeanDefinition  isFactoryMethodUnique=true
	//	return new UserService();
	//}

	//@Bean
	//public UserService userService(OrderService orderService) { //BeanDefinition  isFactoryMethodUnique=false
	//	return new UserService();
	//}

	//@Bean
	//public UserService zhouyu() {
	//
	//	//NullBean
	//	return null;
	//}

	//@Bean
	//public UserService userService1() {
	//	return new UserService();
	//}

	/**
	 * autowireCandidate 当前这个bean可不可以进行依赖注入
	 * 		true: 表示可以
	 * 		false: 表示不可以
	 *
	 * @return
	 */
	////@Bean(autowireCandidate = false)
	//@Bean
	//@Qualifier(value = "b")
	//public OrderService orderService() {
	//	return new OrderService();
	//}
	//
	//@Bean
	//@Qualifier(value = "a")
	//public OrderService orderService1() {
	//	return new OrderService();
	//}


	///**
	// * Java自定义类型转换器的配置类
	// *
	// * @return
	// */
	//@Bean
	//public CustomEditorConfigurer customEditorConfigurer() {
	//	CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer();
	//	Map<Class<?>, Class<? extends PropertyEditor>> propertyEditorMap = new HashMap<>();
	//	propertyEditorMap.put(User.class, StringToUserPropertyEditor.class);
	//	customEditorConfigurer.setCustomEditors(propertyEditorMap);
	//	return customEditorConfigurer;
	//}

	/**
	 * Spring的类型转换器
	 *
	 * @return
	 */
	//@Bean
	//public ConversionServiceFactoryBean conversionService() {
	//	ConversionServiceFactoryBean conversionServiceFactoryBean = new ConversionServiceFactoryBean();
	//	conversionServiceFactoryBean.setConverters(Collections.singleton(new StringToUserConverter()));
	//	return conversionServiceFactoryBean;
	//}
	//
	//
	//@Bean
	//public MessageSource messageSource() {
	//	ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
	//	messageSource.setBasename("messages");
	//	return messageSource;
	//}


	//@Bean
	//public ApplicationListener applicationListener() {
	//	return new ApplicationListener() {
	//		@Override
	//		public void onApplicationEvent(ApplicationEvent event) {
	//			System.out.println("接收到了一个事件" + event);
	//		}
	//	};
	//}

	/**
	 * userService为beanName
	 *
	 * userService1和userService2是bean的别名
	 *
	 * map<"userService1", "userService2">
	 * map<"userService2", "userService">
	 *
	 * @return
	 */
	//@Bean(value = {"userService", "userService1", "userService2"})
	//public UserService userService() {
	//	return new UserService();
	//}

	@Bean
	public JdbcTemplate jdbcTemplate() {
		return new JdbcTemplate(dataSource());
	}
	//
	@Bean
	public PlatformTransactionManager transactionManager() {
		DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
		transactionManager.setDataSource(dataSource());
		////部分失败的情况下，是否全局回滚，默认是true;改成false，就是不回滚
		//transactionManager.setGlobalRollbackOnParticipationFailure(false);
		return transactionManager;
	}

	@Bean
	public DataSource dataSource() {
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/tuling?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai");
		dataSource.setUsername("root");
		dataSource.setPassword("root");
		return dataSource;
	}
	//
	//
	//
	//@Bean
	//public SqlSessionFactory sqlSessionFactory() throws Exception {
	//	SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
	//	sessionFactoryBean.setDataSource(dataSource());
	//	return sessionFactoryBean.getObject();
	//}
	////
	//@Bean
	//public SqlSessionTemplate sqlSession() throws Exception {
	//	SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory());
	//	sqlSessionTemplate.getConfiguration().addMapper(UserMapper.class);
	//	return sqlSessionTemplate;
	//}

}

